home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993…ch: Other People's Memory / ADC Developer CD (1993-03) (''Other People's Memory'')_iso / Dev.CD Mar 93.iso / Technical Documentation / Sample Code / DTS.Lib & Samples / Kibitz / KibitzWindow.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-22  |  16.1 KB  |  615 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        kibitzwindow.c
  5. ** Written by:  Eric Soldan
  6. **
  7. ** Copyright © 1990-1992 Apple Computer, Inc.
  8. ** All rights reserved. */
  9.  
  10.  
  11.  
  12. /*****************************************************************************/
  13.  
  14.  
  15.  
  16. #include "Kibitz.h"                /* Get the Kibitz includes/typedefs, etc.    */
  17. #include "KibitzCommon.h"        /* Get the stuff in common with rez.        */
  18. #include "Kibitz.protos"        /* Get the prototypes for Kibitz.            */
  19.  
  20. #ifndef __ERRORS__
  21. #include <Errors.h>
  22. #endif
  23.  
  24. #ifndef __FONTS__
  25. #include <Fonts.h>
  26. #endif
  27.  
  28. #ifndef __GWLAYERS__
  29. #include <GWLayers.h>
  30. #endif
  31.  
  32. #ifndef __RESOURCES__
  33. #include <Resources.h>
  34. #endif
  35.  
  36. #ifndef __TEXTEDITCONTROL__
  37. #include <TextEditControl.h>
  38. #endif
  39.  
  40. #ifndef __TOOLUTILS__
  41. #include <ToolUtils.h>
  42. #endif
  43.  
  44. #ifndef __UTILITIES__
  45. #include <Utilities.h>
  46. #endif
  47.  
  48.  
  49.  
  50. /*****************************************************************************/
  51.  
  52.  
  53.  
  54. extern short    gPrintPage;                    /* Non-zero means we are printing. */
  55. extern LayerObj    gBoardLayer;
  56. extern short    gClearSquare;
  57.  
  58. CIconHandle        gPieceCIcon[26];
  59.  
  60. static short        gLastPiece[120];
  61. static RgnHandle    gLastColorRgn;
  62.  
  63.  
  64.  
  65. /*****************************************************************************/
  66. /*****************************************************************************/
  67.  
  68.  
  69.  
  70. /* This function adds the application's controls to a window. */
  71.  
  72. #pragma segment Window
  73. OSErr    AppNewWindowControls(FileRecHndl frHndl, WindowPtr window, WindowPtr behind)
  74. {
  75.     OSErr            err;
  76.     TEHandle        mssgIn, mssgOut;
  77.     CTEDataHndl        teData;
  78.     ControlHandle    sendMssg, beepOnMove, beepOnMssg, viewCtl;
  79.     Rect            ctlRect, brdrRect, viewRect, destRect;
  80.     ControlHandle    gameSlider, whiteStarts, blackStarts, resign, draw;
  81.     ControlHandle    record, sendSnd;
  82.     Handle            textHndl;
  83.     Boolean            messageDoc;
  84.     short            mode, fnum;
  85.  
  86.     SetRect(&ctlRect,
  87.             kBoardWidth + 20,
  88.             35,
  89.             rWindowWidth - 20,
  90.             kBoardHalfHeight + kBoardVOffset - 1
  91.     );
  92.  
  93.     brdrRect = viewRect = ctlRect;
  94.     InsetRect(&viewRect, 4, 4);
  95.     destRect = viewRect;
  96.     destRect.right -= 2;
  97.         /* This fixes a TextEdit problem where the view has to be a little
  98.         ** outside the dest on the right, or else characters are clipped.
  99.         */
  100.  
  101.     CTENew(rTECtl,                /* viewCtl of resID for TextEdit control. */
  102.            window,                    /* Window to hold TERecord.                  */
  103.            &mssgIn,                    /* Return handle for TERecord.               */
  104.            &ctlRect,                /* Rect for view control.                  */
  105.            &destRect,                /* destRect for TERecord                  */
  106.            &viewRect,                /* viewRect for TERecord                  */
  107.            &brdrRect,                /* Used to frame a border.                  */
  108.            32000,                    /* Maximum TextEdit document length.      */
  109.            cteReadOnly+cteVScroll    /* TERecord is regular read-only.          */
  110.     );
  111.  
  112.     OffsetRect(&ctlRect, 0, kBoardHalfHeight - 38);
  113.  
  114.     messageDoc = false;
  115.     if ((*frHndl)->doc.myColor == kMessageDoc) messageDoc = true;
  116.     if (messageDoc)
  117.         SetRect(&ctlRect, -1, -1, rWindowWidth - 14, rWindowHeight + 1);
  118.             /* When the window is a message document, the whole window is the outbox.
  119.             ** This keep the actual differences between window kinds to a minimum,
  120.             ** while altering the appearance greatly. */
  121.  
  122.     brdrRect = viewRect = ctlRect;
  123.     InsetRect(&viewRect, 4, 4);
  124.     destRect = viewRect;
  125.     destRect.right -= 2;
  126.  
  127.     mode = cteVScroll;
  128.     if (behind == (WindowPtr)-1)
  129.         if (!(*frHndl)->doc.arrangeBoard)
  130.             mode |= cteActive;
  131.     CTENew(rTECtl, window, &mssgOut, &ctlRect, &destRect, &viewRect, &brdrRect, 32000, mode);
  132.  
  133.     if (mssgOut) {
  134.  
  135.         viewCtl = CTEViewFromTE(mssgOut);
  136.         teData  = (CTEDataHndl)(*viewCtl)->contrlData;
  137.         (*teData)->mode |= cteActive;
  138.             /* Make sure that when a window is activated, the caret blinks.  We need
  139.             ** to do this because the window isn't necessarily opened as the front window.
  140.             ** If we create the TextEdit Control as the active control for a window that
  141.             ** isn't opened as the front window, then we will turn off the caret for
  142.             ** whatever window is the front window.  Al we are doing here is determining
  143.             ** that the message-out TextEdit Control will be the active control when the
  144.             ** window is first brought to the front. */
  145.     
  146.         textHndl = (Handle)(*frHndl)->doc.legalMoves;
  147.         (*frHndl)->doc.legalMoves = (MoveListHndl)CTESwapText(mssgOut, textHndl, false);
  148.             /* AppOpenDocument may have placed some text for the out-box TextEdit
  149.             ** control temporarily in the legalMoves handle.  Move this text into
  150.             ** the out-box TextEdit control. */
  151.     }
  152.  
  153.     if (sendMssg   = GetNewControl(rSendMessage, window)) HiliteControl(sendMssg, 255);
  154.     if (beepOnMove = GetNewControl(rMoveNotify, window))  HiliteControl(beepOnMove, 255);
  155.     if (beepOnMssg = GetNewControl(rMssgNotify, window))  HiliteControl(beepOnMssg, 255);
  156.  
  157.     if (whiteStarts = GetNewControl(rWhiteStarts, window)) {
  158.         OffsetControl(whiteStarts, -4096, 0);
  159.         SetCtlValue(whiteStarts, (*frHndl)->doc.startColor ^ 1);
  160.         ShowControl(whiteStarts);
  161.     }
  162.     if (blackStarts = GetNewControl(rBlackStarts, window)) {
  163.         OffsetControl(blackStarts, -4096, 0);
  164.         SetCtlValue(blackStarts, (*frHndl)->doc.startColor);
  165.         ShowControl(blackStarts);
  166.     }
  167.  
  168.     resign      = GetNewControl(rResign, window);
  169.     draw        = GetNewControl(rDraw, window);
  170.     if (record  = GetNewControl(rRecordSound, window)) HiliteControl(record, 255);
  171.     if (sendSnd = GetNewControl(rSendSound, window))   HiliteControl(sendSnd, 255);
  172.  
  173.     gameSlider = BoardSliderNew(window);
  174.  
  175.     (*frHndl)->doc.message[kMessageIn]  = mssgIn;
  176.     (*frHndl)->doc.message[kMessageOut] = mssgOut;
  177.     (*frHndl)->doc.sendMessage = sendMssg;
  178.     (*frHndl)->doc.beepOnMove  = beepOnMove;
  179.     (*frHndl)->doc.beepOnMssg  = beepOnMssg;
  180.     (*frHndl)->doc.gameSlider  = gameSlider;
  181.     (*frHndl)->doc.wbStart[0]  = whiteStarts;
  182.     (*frHndl)->doc.wbStart[1]  = blackStarts;
  183.     (*frHndl)->doc.resign      = resign;
  184.     (*frHndl)->doc.draw        = draw;
  185.     (*frHndl)->doc.record      = record;
  186.     (*frHndl)->doc.sendSnd     = sendSnd;
  187.  
  188.     if (
  189.         (mssgIn) &&
  190.         (mssgOut) &&
  191.         (sendMssg) &&
  192.         (beepOnMove) &&
  193.         (beepOnMssg) &&
  194.         (gameSlider) &&
  195.         (whiteStarts) &&
  196.         (blackStarts) &&
  197.         (resign) &&
  198.         (draw) &&
  199.         (record) &&
  200.         (sendSnd)
  201.     ) {
  202.         GetFNum("\pMonaco", &fnum);
  203.         (*mssgIn)->txFont = fnum;
  204.         (*mssgIn)->txSize = 9;
  205.         (*mssgOut)->txFont = fnum;
  206.         (*mssgOut)->txSize = 9;
  207.         if (messageDoc) {
  208.             CTEHide(mssgIn);
  209.             HideControl(sendMssg);
  210.             MoveControl(sendMssg, 0, -4096);    /* So no border is drawn. */
  211.             HideControl(beepOnMove);
  212.             HideControl(beepOnMssg);
  213.             HideControl(gameSlider);
  214.             HideControl(whiteStarts);
  215.             HideControl(blackStarts);
  216.             HideControl(resign);
  217.             HideControl(draw);
  218.             HideControl(record);
  219.             HideControl(sendSnd);
  220.         }
  221.         AdjustGameSlider(frHndl);
  222.         err = noErr;
  223.     }
  224.     else
  225.         err = memFullErr;
  226.  
  227.     return(err);
  228. }
  229.  
  230.  
  231.  
  232. /*****************************************************************************/
  233.  
  234.  
  235.  
  236. #pragma segment Window
  237. void    DrawTime(FileRecHndl frHndl)
  238. {
  239.     WindowPtr        oldPort;
  240.     Rect            clockRect;
  241.     short            clock, i, time[3];
  242.     unsigned long    timeLeft, displayTime;
  243.     Str32            pstr, timestr;
  244.  
  245.     if ((*frHndl)->doc.arrangeBoard) return;
  246.  
  247.     oldPort = SetFilePort(frHndl);
  248.  
  249.     TextMode(srcCopy);
  250.     TextFont(systemFont);
  251.  
  252.     for (clock = 0; clock < 2; ++clock) {
  253.  
  254.         clockRect = BoardRect();
  255.  
  256.         if (clock == (*frHndl)->doc.invertBoard)
  257.             clockRect.top += 14;
  258.  
  259.         clockRect.left   = clockRect.right + 26;
  260.         clockRect.right  = clockRect.left + 70;
  261.         clockRect.bottom = clockRect.top + 14;
  262.  
  263.         timeLeft = (*frHndl)->doc.timeLeft[clock];
  264.         if (timeLeft == -1) {
  265.             EraseRect(&clockRect);
  266.             continue;
  267.         }
  268.  
  269.         if ((displayTime = (*frHndl)->doc.displayTime[clock]) > timeLeft)
  270.              displayTime = (*frHndl)->doc.displayTime[clock]  = timeLeft;
  271.  
  272.         MoveTo(clockRect.left + 6, clockRect.top + 14);
  273.  
  274.         for (i = 3; i;) {
  275.             displayTime /= 60;
  276.             time[--i] = displayTime % 60;
  277.         }
  278.         timestr[0] = 0;
  279.         for (i = 0; i < 3; ++i) {
  280.             pcpydec(pstr, time[i]);
  281.             if (pstr[0] == 1) pcat(timestr, "\p0");
  282.             pcat(timestr, pstr);
  283.             pcat(timestr, (StringPtr)"\1:\1:\1 " + (i << 1));    /* Append colon or space. */
  284.         }
  285.         DrawString(timestr);
  286.     }
  287.  
  288.     TextMode(srcOr);
  289.     SetPort(oldPort);
  290. }
  291.  
  292.  
  293.  
  294. /*****************************************************************************/
  295.  
  296.  
  297.  
  298. #pragma segment Window
  299. void    ImageBoardLines(short increment, short hOffset, short vOffset)
  300. {
  301.     short    i;
  302.  
  303.     PenNormal();
  304.     PenSize(1, 1);
  305.  
  306.     for (i = 0; i <= 8; i += increment) {
  307.         MoveTo(hOffset, vOffset + kBoardSqSize * i);
  308.         Line(kBoardSqSize * 8, 0);
  309.         MoveTo(hOffset + kBoardSqSize * i, vOffset);
  310.         Line(0, kBoardSqSize * 8);
  311.     }
  312.  
  313.     PenNormal();
  314. }
  315.  
  316.  
  317.  
  318. /*****************************************************************************/
  319.  
  320.  
  321.  
  322. /* Image the document into the current port. */
  323.  
  324. #pragma segment Window
  325. void    ImageDocument(FileRecHndl frHndl, Boolean justBoard)
  326. {
  327.     short            r, c, rr, cc, piece, pieceIconID, fnum, i;
  328.     short            gameIndex, lastFrom, lastTo, square, ss, hOffset, vOffset;
  329.     Boolean            toWindow, invertBoard, messageDoc;
  330.     LayerObj        windowLayer;
  331.     Rect            sqRect, theInk, boardRect;
  332.     GameListHndl    gameMoves;
  333.     WindowPtr        thePort;
  334.     TEHandle        te;
  335.     Point            pt;
  336.     RgnHandle        colorRgn, testRgn;
  337.     static short    teOffset;
  338.  
  339.     GetPort(&thePort);
  340.  
  341.     toWindow = (thePort == (*frHndl)->fileState.window);
  342.     if (!toWindow) gClearSquare = 0;
  343.  
  344.     messageDoc = false;
  345.     if ((*frHndl)->doc.myColor == kMessageDoc) messageDoc = true;
  346.  
  347.     colorRgn = testRgn = nil;
  348.  
  349.     hOffset = kBoardHOffset;
  350.     vOffset = kBoardVOffset;
  351.     if (gPrintPage > 0) {
  352.         theInk = thePort->portRect;
  353.         GetFNum("\pTimes", &fnum);
  354.         TextFont(fnum);
  355.         TextSize(12);
  356.         TextFace(normal);
  357.         hOffset = theInk.right - 10 - kBoardWidth;
  358.         vOffset = 10;
  359.         if (messageDoc) {
  360.             if (gPrintPage == 1) teOffset = 0;
  361.             te = (*frHndl)->doc.message[kMessageOut];
  362.             InsetRect(&theInk, 4, 4);
  363.             CTEPrint(te, &teOffset, &theInk);
  364.             if (teOffset == -1) gPrintPage = 0;
  365.             return;
  366.         }
  367.         if (thePort->portBits.rowBytes & 0x8000)
  368.             RectRgn(colorRgn = NewRgn(), &theInk);
  369.                 /* Print the board in grayscale or color if user has so chosen. */
  370.     }
  371.     else {
  372.         SetRectRgn(thePort->clipRgn, -30000, -30000, 30000, 30000);
  373.  
  374.         if (!messageDoc) {
  375.             if (!gPrintPage) ImageBoardLines(8, hOffset, vOffset);
  376.  
  377.             colorRgn = ScreenDepthRegion(8);        /* Screen of 8-bit or greater get color icon. */
  378.             pt.h = pt.v = 0;
  379.             GlobalToLocal(&pt);
  380.             OffsetRgn(colorRgn, pt.h, pt.v);        /* Localize the area that gets color icons. */
  381.  
  382.             if (!gPrintPage) SetLayerWorld(gBoardLayer);
  383.         }
  384.     }
  385.  
  386.     if (!colorRgn) colorRgn = NewRgn();
  387.     if (!testRgn)  testRgn  = NewRgn();
  388.  
  389.     if (!gLastColorRgn) gLastColorRgn = NewRgn();
  390.     if ((gPrintPage) || (!EqualRgn(colorRgn, gLastColorRgn)))
  391.         for (i = 0; i < 120; ++i) gLastPiece[i] = 0;
  392.             /* If printing, exporting a board, or if color region has changed, redraw all squares. */
  393.     CopyRgn(colorRgn, gLastColorRgn);
  394.  
  395.     invertBoard = (*frHndl)->doc.invertBoard;
  396.     lastFrom = lastTo = 0;
  397.     gameIndex = (*frHndl)->doc.gameIndex;
  398.     gameMoves = (*frHndl)->doc.gameMoves;
  399.     if (gameIndex) {
  400.         lastFrom = (**gameMoves)[gameIndex - 1].moveFrom;
  401.         lastTo   = (**gameMoves)[gameIndex - 1].moveTo;
  402.         if (!lastFrom) {
  403.             if (gameIndex > 1) {
  404.                 lastFrom = (**gameMoves)[gameIndex - 2].moveFrom;
  405.                 lastTo   = (**gameMoves)[gameIndex - 2].moveTo;
  406.             }
  407.         }
  408.     }
  409.  
  410.     if (gPrintPage < 2) {        /* If not printing, or printing first page... */
  411.         if (!messageDoc) {
  412.             for (r = 0; r < 8; ++r) {
  413.                 if (gClearSquare) r = (gClearSquare - START_IBNDS) / 10;
  414.  
  415.                 for (c = 0; c < 8; ++c) {
  416.                     if (gClearSquare) c = gClearSquare - START_IBNDS - 10 * r;
  417.                 
  418.                     piece = (*frHndl)->doc.theBoard[square = START_IBNDS + 10 * r + c];
  419.                     if (gClearSquare) piece = EMPTY;
  420.                     pieceIconID = piece + KING;
  421.     
  422.                     rr = r;
  423.                     cc = c;
  424.                     if (invertBoard) {
  425.                         rr = 7 - r;
  426.                         cc = 7 - c;
  427.                     }
  428.                     ss = START_IBNDS + 10 * rr + cc;
  429.  
  430.                     if ((rr + cc) & 0x01) pieceIconID += 13;
  431.  
  432.                     if (!gPieceCIcon[pieceIconID])
  433.                         gPieceCIcon[pieceIconID] = ReadCIcon(pieceIconID + 257);
  434.  
  435.                     sqRect.top    = vOffset + kBoardSqSize * rr + 1;
  436.                     sqRect.left   = hOffset + kBoardSqSize * cc + 1;
  437.                     sqRect.bottom = sqRect.top  + 32;
  438.                     sqRect.right  = sqRect.left + 32;
  439.  
  440.                     if (gLastPiece[ss] != pieceIconID + 257) {
  441.                         gLastPiece[ss] = pieceIconID + 257;
  442.                         if (!RectInRgn(&sqRect, colorRgn))        /* If 1-bit, draw b/w icon. */
  443.                             DrawCIconByDepth(gPieceCIcon[pieceIconID], sqRect, 1, false);
  444.                         else {        /* Draw some combo of color and b/w icon. */
  445.                             RectRgn(testRgn, &sqRect);
  446.                             SectRgn(testRgn, colorRgn, testRgn);
  447.                             for (;;) {
  448.                                 if ((*testRgn)->rgnSize == 10) {
  449.                                     if (EqualRect(&((*testRgn)->rgnBBox), &sqRect)) {
  450.                                         DrawCIconByDepth(gPieceCIcon[pieceIconID], sqRect, 8, false);
  451.                                         break;            /* Icon completely on color monitor. */
  452.                                     }
  453.                                 }
  454.                                 DrawCIconByDepth(gPieceCIcon[pieceIconID], sqRect, 1, false);
  455.                                     /* Icon is across two monitors, so first draw it b/w. */
  456.                                 SetClip(testRgn);
  457.                                 DrawCIconByDepth(gPieceCIcon[pieceIconID], sqRect, 8, false);
  458.                                     /* Then redraw the color portion. */
  459.                                 SetRectRgn(testRgn, -30000, -30000, 30000, 30000);
  460.                                 SetClip(testRgn);
  461.                                 break;
  462.                             }
  463.                         }
  464.                     }
  465.  
  466.                     if (!gPrintPage) {
  467.                         if ((square == lastFrom) || (square == lastTo)) {
  468.                             FrameRect(&sqRect);
  469.                             gLastPiece[ss] = 0;
  470.                         }
  471.                     }
  472.  
  473.                     if (gClearSquare) break;
  474.                 }
  475.                 if (gClearSquare) break;
  476.             }
  477.         }
  478.     }
  479.  
  480.     DisposeRgn(colorRgn);
  481.     DisposeRgn(testRgn);
  482.  
  483.     if (!gPrintPage) {
  484.         if (!messageDoc)
  485.             if (!gPrintPage)
  486.                 ResetLayerWorld(gBoardLayer);
  487.         if (toWindow) {
  488.             if (!gClearSquare) {
  489.                 if (!messageDoc) {
  490.                     if (!NewLayer(&windowLayer, nil, nil, thePort, 0, 0)) {
  491.                         InsertLayer(gBoardLayer, windowLayer, 1);
  492.                         boardRect = BoardRect();
  493.                         (*windowLayer)->dstRect = boardRect;
  494.                         InvalLayer(windowLayer, boardRect, false);
  495.                         UpdateLayer(windowLayer);
  496.                         DisposeLayer(windowLayer);
  497.                     }
  498.                 }
  499.             }
  500.         }
  501.     }            
  502.  
  503.     if (gPrintPage) {                /* If printing... */
  504.         if (gPrintPage == 1)        /* If printing page 1... */
  505.             ImageBoardLines(1, hOffset, vOffset);
  506.         ImageMoveList(frHndl, theInk, hOffset);
  507.         return;
  508.     }
  509.  
  510.     if (!justBoard) {
  511.         SetOrigin((*frHndl)->doc.arrangeBoard * 4096, 0);
  512.         if (!messageDoc) UpdateGameStatus(frHndl);
  513.         DoDrawControls(thePort, false);
  514.         if (!messageDoc) {
  515.             OutlineControl((*frHndl)->doc.sendMessage);
  516.             DrawTime(frHndl);
  517.             DrawPalette(frHndl);
  518.         }
  519.         SetOrigin(0, 0);
  520.     }
  521. }
  522.  
  523.  
  524.  
  525. /*****************************************************************************/
  526.  
  527.  
  528.  
  529. #pragma segment Window
  530. void    ImageMoveList(FileRecHndl frHndl, Rect theInk, short hOffset)
  531. {
  532.     short    gameIndex, numGameMoves, printMoveNum, colsPerPage, colHeight;
  533.     short    pageNum, colNum, colVOffset, numMovePairs, colEndMove, hloc, vloc;
  534.     Str255    pstr;
  535.  
  536.     gameIndex    = (*frHndl)->doc.gameIndex;
  537.     numGameMoves = (*frHndl)->doc.numGameMoves;
  538.     printMoveNum = (*frHndl)->doc.startColor;
  539.     colsPerPage  = (theInk.right  - theInk.left) / 180;
  540.     colHeight    = (theInk.bottom - theInk.top) - 2 * kBoardHOffset;
  541.  
  542.     for (pageNum = 1; pageNum <= gPrintPage; ++pageNum) {
  543.  
  544.         for (colNum = 1; colNum <= colsPerPage; ++colNum) {
  545.  
  546.             hloc = colNum * 180 - 120;
  547.  
  548.             colVOffset = 0;
  549.             if (pageNum == 1) {
  550.                 if (colNum == 1) colVOffset = (3 * 20);
  551.                 if (hloc + 130 >= hOffset)
  552.                     for (; colVOffset < (kBoardHeight + 20 + kBoardVOffset); colVOffset += 20);
  553.                         /* Start this column below the board on 20-pixel boundary. */
  554.             }
  555.  
  556.             numMovePairs = (colHeight - colVOffset) / 20;
  557.             colEndMove   = printMoveNum + 2 * numMovePairs;
  558.  
  559.             if (pageNum == gPrintPage) {
  560.  
  561.                 if ((pageNum == 1) && (colNum == 1)) {
  562.                     MoveTo(hloc, theInk.top + 20);
  563.                     pcpy(pstr, (*frHndl)->fileState.fss.name);
  564.                     TextFace(bold + underline);
  565.                     DrawString(pstr);
  566.                     TextFace(normal);
  567.                 }
  568.  
  569.                 for (; printMoveNum < colEndMove; ++printMoveNum) {
  570.  
  571.                     RepositionBoard(frHndl, printMoveNum, false);
  572.  
  573.                     if (printMoveNum >= numGameMoves) {
  574.                         gPrintPage = 0;
  575.                         RepositionBoard(frHndl, gameIndex, false);
  576.                         return;
  577.                     }
  578.  
  579.                     vloc = theInk.top + colVOffset + 20;
  580.  
  581.                     if (!(printMoveNum & 0x01)) {
  582.                         pcpydec(pstr, printMoveNum / 2 + 1);
  583.                         MoveTo(hloc - 16 - StringWidth(pstr), vloc);
  584.                         DrawString(pstr);
  585.                         DrawString("\p)");
  586.                         MoveTo(hloc, vloc);
  587.                     }
  588.                     else {
  589.                         MoveTo(hloc + 40, vloc);
  590.                         MoveTo(hloc + 40 + 12, vloc);
  591.                         colVOffset += 20;
  592.                     }
  593.  
  594.                     if (Algebraic(frHndl, printMoveNum, gameIndex, pstr))
  595.                         TextFace(underline);
  596.  
  597.                     DrawString(pstr);
  598.                     TextFace(normal);
  599.                 }
  600.             }
  601.  
  602.             if ((printMoveNum = colEndMove) >= numGameMoves) {
  603.                 gPrintPage = 0;
  604.                 RepositionBoard(frHndl, gameIndex, false);
  605.                 return;
  606.             }
  607.         }
  608.     }
  609.  
  610.     RepositionBoard(frHndl, gameIndex, false);
  611. }
  612.  
  613.  
  614.  
  615.